home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 October / CHIP Turkiye Ekim 2000.iso / prog / naps / 04 / setup.exe / Gnucleus / TitleTip.cpp < prev    next >
C/C++ Source or Header  |  2000-07-06  |  8KB  |  293 lines

  1. /********************************************************************************
  2.  
  3.     Gnucleus - A node application for the Gnutella network
  4.     Copyright (C) 2000 John Marshall
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  
  19.     For support, questions, comments, etc...
  20.     E-Mail: 
  21.         swabby@c0re.net
  22.     
  23.     Address:
  24.         21 Cadogan Way
  25.         Nashua, NH, USA 03062
  26.  
  27. ********************************************************************************/
  28.  
  29. #include "stdafx.h"
  30. #include "TitleTip.h"
  31.  
  32. #ifdef _DEBUG
  33. #define new DEBUG_NEW
  34. #undef THIS_FILE
  35. static char THIS_FILE[] = __FILE__;
  36. #endif
  37.  
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CTitleTip
  40.  
  41. CTitleTip::CTitleTip()
  42. {
  43.     m_iHorzSpace = 2;
  44.     m_brshBackground = (HBRUSH)0;
  45.  
  46.     m_clrBackground = ::GetSysColor(COLOR_HIGHLIGHT);
  47.     m_clrText = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
  48.  
  49.     RegisterWindowClass();                                        // Register window class if not already registered.
  50. }
  51.  
  52. CTitleTip::~CTitleTip()
  53. {
  54. }
  55.  
  56. // static
  57. void
  58. CTitleTip::RegisterWindowClass()
  59. {
  60.     WNDCLASS wndcls;
  61.     HINSTANCE hInst = AfxGetInstanceHandle();
  62.     if(!(::GetClassInfo(hInst, TITLETIP_CLASSNAME, &wndcls)))
  63.     {
  64.         // otherwise we need to register a new class
  65.         wndcls.style = CS_SAVEBITS | CS_DBLCLKS;
  66.         wndcls.lpfnWndProc = ::DefWindowProc;
  67.         wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
  68.         wndcls.hInstance = hInst;
  69.         wndcls.hIcon = NULL;
  70.         wndcls.hCursor = LoadCursor( hInst, IDC_ARROW );
  71.         wndcls.hbrBackground = (HBRUSH)(COLOR_INFOBK + 1); 
  72.         wndcls.lpszMenuName = NULL;
  73.         wndcls.lpszClassName = TITLETIP_CLASSNAME;
  74.         if (!AfxRegisterClass(&wndcls))
  75.             AfxThrowResourceException();
  76.     }
  77. }
  78.  
  79.  
  80. BEGIN_MESSAGE_MAP(CTitleTip, CWnd)
  81.     //{{AFX_MSG_MAP(CTitleTip)
  82.     ON_WM_MOUSEMOVE()
  83.     //}}AFX_MSG_MAP
  84. END_MESSAGE_MAP()
  85.  
  86. void CTitleTip::SetBackground(HBRUSH brshBackground)
  87. {
  88.     m_brshBackground = brshBackground;
  89. }
  90.  
  91. void CTitleTip::SetBkColor(COLORREF crColor)
  92. {
  93.     m_clrBackground = crColor;
  94. }
  95.  
  96. void CTitleTip::SetTextColor(COLORREF crColor)
  97. {
  98.     m_clrText = crColor;
  99. }
  100.  
  101. /////////////////////////////////////////////////////////////////////////////
  102. // CTitleTip message handlers
  103.  
  104. /*
  105. * styles:
  106. * <UL>
  107. *   <LI>WS_BORDER: draws a border around the titletip window
  108. *   <LI>WS_POPUP:  needed so that the TitleTip window is able to extend
  109. *     beyond the boundary of the control
  110. *   <LI>WS_EX_TOOLWINDOW: stops the window from appearing in the task bar
  111. *   <LI>WS_EX_TOPMOST:    ensures the titletip is visible
  112. *   <LI>COLOR_INFOBK:     the same color used by ToolTip
  113. * </UL>
  114. */
  115.  
  116. BOOL CTitleTip::Create(CWnd * pParentWnd)
  117. {
  118.     ASSERT_VALID(pParentWnd);
  119.     
  120.     DWORD dwStyle = WS_BORDER | WS_POPUP; 
  121.     DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
  122.     m_pParentWnd = pParentWnd;
  123.     return CreateEx( dwExStyle, TITLETIP_CLASSNAME, NULL, dwStyle, 0, 0, 0, 0, 
  124.         NULL, NULL, NULL );
  125. }
  126.  
  127. /**
  128. * This gets called repeatedly by its parent control.
  129. * Determines whether the text extent of pszTitleText is too big for the
  130. * original rectangle (rectTitle) and displays a TitleTip if required.
  131. *
  132. * @memo Displays the titletip if required.
  133. *
  134. * @param rectTitle  rectangle for the original title - in client coordinates
  135. * @param sTitleText text to be displayed
  136. * @param xoffset    number of pixel the text is offset from left border of the cell
  137. */
  138.  
  139. void CTitleTip::Show(CRect rectTitle, CString sTitleText, int xoffset /*=0*/)
  140. {
  141.     ASSERT(::IsWindow(m_hWnd));
  142.     ASSERT(!rectTitle.IsRectEmpty());
  143.     
  144.     if(GetFocus() == NULL)                    // only display titletip if app has focus
  145.         return;
  146.     
  147.     // Define the rectangle outside which the titletip will be hidden.
  148.     m_rectTitle.top = 0;
  149.     m_rectTitle.left = -xoffset;
  150.     m_rectTitle.right = rectTitle.Width() - xoffset;
  151.     m_rectTitle.bottom = rectTitle.Height();
  152.  
  153.     m_pParentWnd->ClientToScreen(rectTitle);  // Determine the width of the text
  154.     
  155.     CClientDC dc(this);
  156.     int iSavedDC = dc.SaveDC();               // Save DC state
  157.  
  158.     dc.SelectObject(m_pParentWnd->GetFont());    // use same font as ctrl
  159.     
  160.     CSize size = dc.GetTextExtent(sTitleText);
  161.     CRect rectDisplay = rectTitle;
  162.     rectDisplay.left += xoffset - GetHorzSpace();
  163.     rectDisplay.right = rectDisplay.left + size.cx + 2 + 2*GetHorzSpace();
  164.     
  165.     // Do not display if the text fits within available space
  166.     if(size.cx <= rectTitle.Width()-2*xoffset-2)
  167.         return;
  168.     
  169.     // Show the titletip
  170.     SetWindowPos(&wndTop, rectDisplay.left, rectDisplay.top, 
  171.         rectDisplay.Width(), rectDisplay.Height(), 
  172.         SWP_SHOWWINDOW|SWP_NOACTIVATE);
  173.  
  174.  
  175.     if(m_brshBackground)
  176.     {
  177.         dc.SetTextColor(m_clrText);
  178.         dc.SetBkColor(m_clrBackground);
  179.         dc.SetBkMode(OPAQUE);
  180.         dc.SelectObject(CBrush::FromHandle(m_brshBackground));
  181.         dc.FillSolidRect(0, 0, rectDisplay.Width(), rectDisplay.Height(), m_clrBackground);
  182.     }
  183.     else
  184.     {
  185.         dc.SetBkMode(TRANSPARENT);
  186.     }
  187.  
  188.     dc.TextOut(GetHorzSpace(), 0, sTitleText);
  189.  
  190.     dc.RestoreDC(iSavedDC);                   // Restore DC.
  191.     
  192.     SetCapture();
  193. }
  194.  
  195. /*
  196. * Hide if the mouse is outside the original rectangle. Note that this is
  197. * smaller than the actual window rectangle.
  198. */
  199. void CTitleTip::OnMouseMove(UINT nFlags, CPoint point) 
  200. {
  201.     if(!m_rectTitle.PtInRect(point))
  202.     {
  203.         ReleaseCapture();
  204.         ShowWindow(SW_HIDE);
  205.         
  206.         // Forward the message
  207.         ClientToScreen(&point);
  208.         CWnd *pWnd = WindowFromPoint(point);
  209.         if(pWnd == this) 
  210.             pWnd = m_pParentWnd;
  211.         int hittest = (int)pWnd->SendMessage(WM_NCHITTEST,0,MAKELONG(point.x,point.y));
  212.         if(hittest == HTCLIENT)
  213.         {
  214.             pWnd->ScreenToClient(&point);
  215.             pWnd->PostMessage(WM_MOUSEMOVE, nFlags, MAKELONG(point.x,point.y));
  216.         }
  217.         else
  218.         {
  219.             pWnd->PostMessage( WM_NCMOUSEMOVE, hittest, MAKELONG(point.x,point.y));
  220.         }
  221.     }
  222. }
  223.  
  224. BOOL CTitleTip::PreTranslateMessage(MSG* pMsg) 
  225. {
  226.     CWnd *pWnd;
  227.     int hittest ;
  228.     switch(pMsg->message)
  229.     {
  230.     case WM_LBUTTONDBLCLK:
  231.     case WM_RBUTTONDBLCLK:
  232.     case WM_MBUTTONDBLCLK:
  233.     case WM_LBUTTONUP:
  234.     case WM_RBUTTONUP:
  235.     case WM_MBUTTONUP:
  236.     case WM_LBUTTONDOWN:
  237.     case WM_RBUTTONDOWN:
  238.     case WM_MBUTTONDOWN:
  239.         POINTS pts = MAKEPOINTS(pMsg->lParam);
  240.         POINT  point;
  241.         point.x = pts.x;
  242.         point.y = pts.y;
  243.         ClientToScreen(&point);
  244.         pWnd = WindowFromPoint(point);
  245.         if(pWnd == this) 
  246.             pWnd = m_pParentWnd;
  247.         
  248.         hittest = (int)pWnd->SendMessage(WM_NCHITTEST,0,MAKELONG(point.x,point.y));
  249.         if(hittest == HTCLIENT)
  250.         {
  251.             pWnd->ScreenToClient(&point);
  252.             pMsg->lParam = MAKELONG(point.x,point.y);
  253.         }
  254.         else
  255.         {
  256.             switch(pMsg->message)
  257.             {
  258.             case WM_LBUTTONDOWN: 
  259.                 pMsg->message = WM_NCLBUTTONDOWN;
  260.                 break;
  261.             case WM_RBUTTONDOWN: 
  262.                 pMsg->message = WM_NCRBUTTONDOWN;
  263.                 break;
  264.             case WM_MBUTTONDOWN: 
  265.                 pMsg->message = WM_NCMBUTTONDOWN;
  266.                 break;
  267.             }
  268.             pMsg->wParam = hittest;
  269.             pMsg->lParam = MAKELONG(point.x,point.y);
  270.             ShowWindow(SW_HIDE);
  271.         }
  272.         pWnd->SendMessage(pMsg->message,pMsg->wParam,pMsg->lParam);
  273.         if(GetCapture() == NULL)
  274.             SetCapture();
  275.         return TRUE;                        
  276.     case WM_KEYDOWN:
  277.     case WM_SYSKEYDOWN:
  278.         ReleaseCapture();
  279.         ShowWindow(SW_HIDE);
  280.         m_pParentWnd->PostMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
  281.         return TRUE;
  282.     }
  283.     
  284.     if(GetFocus() == NULL)
  285.     {
  286.         ReleaseCapture();
  287.         ShowWindow(SW_HIDE);
  288.         return TRUE;
  289.     }
  290.     
  291.     return CWnd::PreTranslateMessage(pMsg);
  292. }
  293.